package com.lin.controller;


import com.lin.util.RabbitUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.MessageProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.nio.charset.StandardCharsets;

@RequestMapping("/demo2")
@Controller
public class Demo2 {

    /*
     *    简单理解RabbitMQ的消息ACK机制：
     *                  （只是大概了解--这里的实现都是自己的想象）
     *                   我们可以通过设置queue的参数来将queue设置成ACK机制，确保消息一定会被消费掉
     *                   1.消息分配给一个Consumer，将消息移出队列，可能移动到特定消费者的unAck消息队列中去。
     *                   2.Consumer消费消息 在完成消息之后 返回一个ACK信号给MQ 告诉它消息已经被消费了。
     *                   3.  如果消息被消费发送ack那么代表成功消费，将unAck队列中的相应消息删除。
     *                       如果Consumer tcp连接断开 或者 connection断开 但是没有发送ack 那么就将消息从unAck队列中删除 并重新加入queue中
     *                       如果Consumer 长时间没有回复ack （默认时间30min） 那么消费者channel会自动发送一个ack（避免MQ的存储爆炸）
     *
     *                  消费者发送ack我们可以手动调用也可以设置让channel自动发送
     *                      1.手动调用没什么好说的
     *                      2.自动发送原理可能是 在我们的回调函数返回后 channel自动发送相应的ack
     *
     *    消费者限流机制：channel.basicQos(num);
     *                 可以用来保证当前消费者最多同时处理多少个消息
     */

    @Value("${queue.demo2_queue_name}")
    private String QUEUE_NAME;

    // localhost:8080/demo2/sendTask/5
    @RequestMapping("sendTask/{second}")
    @ResponseBody
    public String sendTask(@PathVariable Integer second){
        try (Connection connection = RabbitUtil.getConnection();
             Channel channel = connection.createChannel();
         ) {
//          这里设置成true表示消息需要被ack
//          创建一个队列（如果不存在）
            channel.queueDeclare(QUEUE_NAME,true,false,false,null);
            String message = "work" + second;
            channel.basicPublish("",QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "资本家的力量,成功命令工人去工作";
    }
}
